package in.waffl.fairycake;

import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

public class Block {
	private static ArrayList<Block> blocks = new ArrayList<Block>();
	private int x;
	private int y;
	private int width;
	private int height;
	private Drawable drawable;
	private boolean edge = true;
	private Block(int x, int y, int width, int height, final BufferedImage tiles, final int tileIndex, final Canvas canvas) {
		this.setX(x);
		this.setY(y);
		this.setWidth(width);
		this.setHeight(height);
		final BufferedImage tile = tiles.getSubimage(tileIndex*20, 0, 20, 20);
		this.drawable = new Drawable() {
			@Override
			public void draw(Graphics2D g) {
				g.drawImage(tile, getX(), getY(), getWidth(), getHeight(), canvas);
			}
		};
		canvas.addDrawable(drawable);
	}
	public int getX() {
		return x;
	}
	public void setX(int x) {
		this.x = x;
	}
	public int getY() {
		return y;
	}
	public void setY(int y) {
		this.y = y;
	}
	public int getWidth() {
		return width;
	}
	public void setWidth(int width) {
		this.width = width;
	}
	public int getHeight() {
		return height;
	}
	public void setHeight(int height) {
		this.height = height;
	}
	public static Block createBlock(int x, int y, int width, int height, BufferedImage tiles, int tileIndex, Canvas canvas) {
		synchronized (blocks) {
			Block block = new Block(x, y, width, height, tiles, tileIndex, canvas);
			blocks.add(block);
			return block;
		}
	}
	public static Block collisionPoint(Point p) {
		synchronized (blocks) {
			for (Block b : blocks) {
				if (p.x > b.getX() && p.x < b.getX() + b.getWidth()
						&& p.y > b.getY() && p.y < b.getY() + b.getHeight())
					return b;
			}
			return null;
		}
	}
	public static Block collisionLine(Point p1, Point p2) {
		synchronized (blocks) {
			Line2D l = new Line2D.Float(p1, p2);
			for (Block b : blocks) {
				if (l.intersects(b.getX(), b.getY(), b.getWidth(), b.getHeight())) return b;
			}
			return null;
		}
	}
	public static Block collisionRectangle(Rectangle r) {
		synchronized (blocks) {
			for (Block b : blocks) {
				if (r.intersects(new Rectangle(b.getX(), b.getY(), b.getWidth(), b.getHeight()))) return b;
			}
			return null;
		}
	}
	public static Block collisionRectangleTop(Rectangle r) {
		synchronized (blocks) {
			for (Block b : blocks) {
				if (r.intersectsLine(b.getX(), b.getY(), b.getX()+b.getWidth(), b.getY())) return b;
			}
			return null;
		}
	}
	public boolean isEdge() {
		return edge;
	}
	public void setEdge(boolean edge) {
		this.edge = edge;
	}
	public static void destroyAll() {
		synchronized (blocks) {
			for (Block b : blocks) {
				b.destroy(false);
			}
			blocks.clear();
		}
	}
	private void destroy(boolean remove) {
		synchronized (blocks) {
			if (remove) blocks.remove(this);
			drawable.destroy = true;
		}
	}
	public void destroy() {
		destroy(true);
	}
}
